/**  
* Copyright (c) 2009, Noel Lynch All rights reserved. Redistribution and use  
* in source and binary forms, with or without modification, are permitted  
* provided that the following conditions are met: Redistributions of source  
* code must retain the above copyright notice, this list of conditions and the  
* following disclaimer. Redistributions in binary form must reproduce the above  
* copyright notice, this list of conditions and the following disclaimer in the  
* documentation and/or other materials provided with the distribution. Neither  
* the name of Noel Lynch nor the names of contributors may be used to  
* endorse or promote products derived from this software without specific prior  
* written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
*/
// created by noellynch
// Oct 16, 2009

package com.sceneworker.util.swing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;

import com.myjavautils.math.MathUtils;
import com.myjavautils.swing.DrawUtils;
import com.myjavautils.swing.SwingComponentFactory;

public class RGBEditorPanel extends JPanel {

	private		ColourComponent			mcl_resultColorComponent;
	private		IColourChanged			mcl_colourChangedListener;
	
	static	private		Dimension		COLOUR_COMP_DIM = new Dimension(6, 17);
	static	private		Dimension		RESULT_COMP_DIM = new Dimension(20, 17);
	
	public	RGBEditorPanel() {
		setLayout(new MigLayout("inset 5"));
		
		JLabel		lcl_redLbl = SwingComponentFactory.makeALabel("R :");
		final	JTextField	lcl_redField = SwingComponentFactory.makeANumberTextField(255);
		final	ColourComponent	lcl_redDrag = new ColourComponent(1, 0, 0, true, COLOUR_COMP_DIM);
		
		JLabel		lcl_greenLbl = SwingComponentFactory.makeALabel("G :");
		final	JTextField	lcl_greenField = SwingComponentFactory.makeANumberTextField(255);
		final	ColourComponent	lcl_greenDrag = new ColourComponent(0, 1, 0, true, COLOUR_COMP_DIM);
		
		JLabel		lcl_blueLbl = SwingComponentFactory.makeALabel("B :");
		final	JTextField	lcl_blueField = SwingComponentFactory.makeANumberTextField(255);
		final	ColourComponent	lcl_blueDrag = new ColourComponent(0, 0, 1, true, COLOUR_COMP_DIM);
		
		JLabel		lcl_resultLbl = SwingComponentFactory.makeALabel(" = ");
		mcl_resultColorComponent = new ColourComponent(1, 1, 1, true, RESULT_COMP_DIM);
		
		lcl_redField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				try {
					int		li_newValue = Integer.parseInt(lcl_redField.getText());
					lcl_redDrag.setValue(li_newValue);
					mcl_resultColorComponent.setValueAt(li_newValue, 0);
					if(mcl_colourChangedListener != null) {
						mcl_colourChangedListener.colourChanged(mcl_resultColorComponent.getValueAt(0), mcl_resultColorComponent.getValueAt(1), mcl_resultColorComponent.getValueAt(2));
					}
					repaint();
				} catch (NumberFormatException e1) {
				}
			}
		});
		
		lcl_redDrag.setColourComponentDragListener(new IColourComponentDragger() {
			public void componentDragged() {
				lcl_redField.setText("" + lcl_redDrag.getValueAt(0));
				mcl_resultColorComponent.setValueAt(lcl_redDrag.getValueAt(0), 0);
				if(mcl_colourChangedListener != null) {
					mcl_colourChangedListener.colourChanged(mcl_resultColorComponent.getValueAt(0), mcl_resultColorComponent.getValueAt(1), mcl_resultColorComponent.getValueAt(2));
				}
				repaint();
			}
			
		});
		
		lcl_greenField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				try {
					int		li_newValue = Integer.parseInt(lcl_greenField.getText());
					lcl_greenDrag.setValue(li_newValue);
					mcl_resultColorComponent.setValueAt(li_newValue, 1);
					if(mcl_colourChangedListener != null) {
						mcl_colourChangedListener.colourChanged(mcl_resultColorComponent.getValueAt(0), mcl_resultColorComponent.getValueAt(1), mcl_resultColorComponent.getValueAt(2));
					}
					repaint();
				} catch (NumberFormatException e1) {
				}
			}
		});
		
		lcl_greenDrag.setColourComponentDragListener(new IColourComponentDragger() {
			public void componentDragged() {
				lcl_greenField.setText("" + lcl_greenDrag.getValueAt(1));
				mcl_resultColorComponent.setValueAt(lcl_greenDrag.getValueAt(1), 1);
				if(mcl_colourChangedListener != null) {
					mcl_colourChangedListener.colourChanged(mcl_resultColorComponent.getValueAt(0), mcl_resultColorComponent.getValueAt(1), mcl_resultColorComponent.getValueAt(2));
				}
				repaint();
			}
			
		});
		
		lcl_blueField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				try {
					int		li_newValue = Integer.parseInt(lcl_blueField.getText());
					lcl_blueDrag.setValue(li_newValue);
					mcl_resultColorComponent.setValueAt(li_newValue, 2);
					if(mcl_colourChangedListener != null) {
						mcl_colourChangedListener.colourChanged(mcl_resultColorComponent.getValueAt(0), mcl_resultColorComponent.getValueAt(1), mcl_resultColorComponent.getValueAt(2));
					}
					repaint();
				} catch (NumberFormatException e1) {
				}
			}
		});
		
		lcl_blueDrag.setColourComponentDragListener(new IColourComponentDragger() {
			public void componentDragged() {
				lcl_blueField.setText("" + lcl_blueDrag.getValueAt(2));
				mcl_resultColorComponent.setValueAt(lcl_blueDrag.getValueAt(2), 2);
				if(mcl_colourChangedListener != null) {
					mcl_colourChangedListener.colourChanged(mcl_resultColorComponent.getValueAt(0), mcl_resultColorComponent.getValueAt(1), mcl_resultColorComponent.getValueAt(2));
				}
				repaint();
			}
			
		});
		
		add(lcl_redLbl);
		add(lcl_redField);
		add(lcl_redDrag);
		
		add(lcl_greenLbl);
		add(lcl_greenField);
		add(lcl_greenDrag);
		
		add(lcl_blueLbl);
		add(lcl_blueField);
		add(lcl_blueDrag);
		
		add(lcl_resultLbl);
		add(mcl_resultColorComponent);
	}
	
	public	void	setColourChangedListener(IColourChanged cl_l) {
		mcl_colourChangedListener = cl_l;
	}
	
	private	class	ColourComponent extends JComponent {
		private		int		mia_mask[] = { 1, 1, 1};
		private		int		mia_values[] = { 255, 255, 255 };
		private		int		mi_lastY;
		private		Dimension		mcl_dim;
		private		IColourComponentDragger		mcl_listener;
		
		public	ColourComponent(int i_redMask, int i_greenMask, int i_blueMask, boolean b_dragEnabled, Dimension cl_dim) {
			mcl_dim = cl_dim;
			mia_mask[0] = i_redMask;
			mia_mask[1] = i_greenMask;
			mia_mask[2] = i_blueMask;
			
			if(b_dragEnabled) {
				addMouseMotionListener(new MouseMotionListener() {
					public void mouseDragged(MouseEvent e) {
						if(mi_lastY < e.getPoint().y) {
							mia_values[0] -= 5;
							mia_values[1] -= 5;
							mia_values[2] -= 5;
						} else {
							mia_values[0] += 5;
							mia_values[1] += 5;
							mia_values[2] += 5;
						}
						
						mi_lastY = e.getPoint().y;
						mia_values[0] = MathUtils.limit(mia_values[0], 0, 255);
						mia_values[1] = MathUtils.limit(mia_values[1], 0, 255);
						mia_values[2] = MathUtils.limit(mia_values[2], 0, 255);
						
						if(mcl_listener != null) {
							mcl_listener.componentDragged();
						}
						
						repaint();
					}

					public void mouseMoved(MouseEvent e) {
					}
					
				});
			}
		}
		
		public	void	setColourComponentDragListener(IColourComponentDragger cl_l) {
			mcl_listener = cl_l;
		}
		
		public	void	setValueAt(int i_value, int i_offset) {
			 mia_values[i_offset] = MathUtils.limit(i_value, 0, 255);
		}
		
		public	int		getValueAt(int i_offset) {
			return mia_values[i_offset];
		}
		
		public	void	setValue(int i_value) {
			mia_values[0] = MathUtils.limit(i_value, 0, 255);
			mia_values[1] = MathUtils.limit(i_value, 0, 255);
			mia_values[2] = MathUtils.limit(i_value, 0, 255);
		}

		@Override
		public Dimension getMaximumSize() {
			return getPreferredSize();
		}

		@Override
		public Dimension getMinimumSize() {
			return getPreferredSize();
		}

		@Override
		public Dimension getPreferredSize() {
			return mcl_dim;
		}

		@Override
		protected void paintComponent(Graphics cl_g) {
			cl_g.setColor(new Color(mia_mask[0] * mia_values[0], mia_mask[1] * mia_values[1], mia_mask[2] * mia_values[2]));
			DrawUtils.fillComponentRect(cl_g, this);
		}
		
	}
	
	private	interface	IColourComponentDragger {
		void	componentDragged();
	}
	
	public	interface	IColourChanged {
		void	colourChanged(int i_r, int i_g, int i_b);
	}
}
